package com.acme.bankapp.service.bank;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.acme.bankapp.domain.bank.Account;
import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.domain.bank.Client;

/**
 * Provides various kind of statistics for bank.
 * 
 */
public final class BankReport {
	/**
	 * Returns number of clients in the bank.
	 * 
	 * @param bank
	 *            bank
	 * @return number of clients
	 */
	public static int getNbOfCustomers(Bank bank) {
		return bank.getClients().size();
	}

	/**
	 * Returns total number of accounts for all clients in the bank.
	 * 
	 * @param bank
	 *            bank
	 * @return total number of accounts
	 */
	public static int getNbOfAccounts(Bank bank) {
		return bank.getAccounts().size();
	}

	/**
	 * Returns all accounts in the bank sorted by balance in ascending order.
	 * 
	 * @param bank
	 *            bank
	 * @return sorted list of accounts
	 */
	public static List<Account> getAccountsSortedBySum(Bank bank) {
		List<Account> accounts = new ArrayList<>(bank.getAccounts());
		Collections.sort(accounts, new Comparator<Account>() {
			public int compare(Account account1, Account account2) {
				return Double.compare(account1.getBalance(),
						account2.getBalance());
			}
		});
		return accounts;
	}

	/**
	 * Returns total credit, that bank clients have.
	 * 
	 * @param bank
	 *            bank
	 * @return total amount of credit
	 */
	public static double getBankCredit(Bank bank) {
		double totalCredit = 0;
		for (Account account : bank.getAccounts()) {
			if (account.getBalance() < 0) {
				totalCredit += -account.getBalance();
			}
		}
		return totalCredit;
	}

	/**
	 * Returns a map Client -> Set of accounts.
	 * 
	 * @param bank
	 *            bank
	 * @return map
	 */
	public static Map<Client, Set<Account>> getCustomerAccount(Bank bank) {
		Map<Client, Set<Account>> map = new LinkedHashMap<Client, Set<Account>>();
		for (Client client : bank.getClients()) {
			map.put(client, client.getAccounts());
		}
		return map;
	}
}
